package com.crt.nexus.core.util;

import lombok.SneakyThrows;
import lombok.experimental.UtilityClass;

@SuppressWarnings("unused")
@UtilityClass
public class StringUtils extends org.apache.commons.lang3.StringUtils {

	public static final String SLASH = "/";
	private static final String EXPR_ASCII = "[\\p{ASCII}]+";

	public boolean startWith(CharSequence str, CharSequence prefix, boolean isIgnoreCase) {
		if (null != str && null != prefix) {
			return isIgnoreCase ? str.toString().toLowerCase().startsWith(prefix.toString().toLowerCase()) : str.toString().startsWith(prefix.toString());
		} else {
			return null == str && null == prefix;
		}
	}

	public String removePrefix(CharSequence cs, CharSequence prefix) {
		if (isNotEmpty(cs) && isNotEmpty(prefix)) {
			String string = cs.toString();
			return string.startsWith(prefix.toString()) ? subSuf(string, prefix.length()) : string;
		} else {
			return null == cs ? null : cs.toString();
		}
	}

	public boolean isEmpty(CharSequence c) {
		return c == null || c.length() == 0;
	}

	/**
	 * To judge whether a string is null or is blank.
	 * <p>
	 * If this string contains only blanks, this string would be considered to be blank.
	 *
	 * @return <code>true</code> on null or blank
	 */
	public boolean isEmpty(String s) {
		return s == null || s.trim().length() == 0;
	}

	public boolean isNotEmpty(CharSequence c) {
		return c != null && c.length() != 0;
	}

	public boolean isNotEmpty(String s) {
		return s != null && s.trim().length() != 0;
	}

	public String subSuf(CharSequence string, int fromIndex) {
		return isEmpty(string) ? null : sub(string, fromIndex, string.length());
	}

	public String sub(CharSequence cs, int fromIndex, int toIndex) {
		if (cs == null || cs.length() == 0) {
			return null == cs ? null : cs.toString();
		} else {
			int len = cs.length();
			if (fromIndex < 0) {
				fromIndex += len;
				if (fromIndex < 0) {
					fromIndex = 0;
				}
			} else if (fromIndex > len) {
				fromIndex = len;
			}
			if (toIndex < 0) {
				toIndex += len;
				if (toIndex < 0) {
					toIndex = len;
				}
			} else if (toIndex > len) {
				toIndex = len;
			}
			if (toIndex < fromIndex) {
				int tmp = fromIndex;
				fromIndex = toIndex;
				toIndex = tmp;
			}
			return fromIndex == toIndex ? "" : cs.toString().substring(fromIndex, toIndex);
		}
	}

	public CharSequence firstChar(CharSequence cs) {
		if (isNotEmpty(cs)) {
			return cs.subSequence(0, 1);
		} else {
			return null == cs ? null : cs.toString();
		}
	}

	@SneakyThrows
	public String maskString(String string, int start, int end, char maskChar) {
		if (string == null || string.equals("")) return string;
		if (start < 0) start = 0;
		if (end > string.length()) end = string.length();
		if (start > end) throw new Exception("End index cannot be greater than start index");
		int maskLength = end - start;
		if (maskLength == 0) return string;
		return string.substring(0, start) + String.valueOf(maskChar).repeat(maskLength) + string.substring(start + maskLength);
	}

	/**
	 * Is all the String is ACSII.
	 *
	 * @param str the string
	 * @return true if all string is ASCII; else false.
	 */
	public static boolean isAscii(String str) {
		return str.matches(EXPR_ASCII);
	}

}
